/*
 * @lc app=leetcode.cn id=142 lang=typescript
 *
 * [142] 环形链表 II
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */
//  思路：快慢指针
//  第一次相遇：慢指针走了k 步 快指针走了2k 步
//  环的长度为k，快指针走 k-m 到达环起点
//  第二次相遇：慢指针从开头走 k-m 到达环起点
//  参考：https://labuladong.github.io/algo/2/19/18/

//  复杂度： O(n)  O(1)

function detectCycle(head: ListNode | null): ListNode | null {
    let fast = head, slow = head

    while (slow && fast && fast.next) {
        slow = slow.next
        fast = fast.next.next
        if (fast === slow) break
    }

    // fast 遇到空指针说明没有环
    if (!fast || !fast.next) return null

    slow = head

    // 快慢指针同步前进，相交点就是环起点
    while (slow !== fast) {
        fast = fast!.next
        slow = slow!.next
    }
    return slow
};
// @lc code=end
import { ListNode } from './type'

let head = new ListNode(3)
let node2 = new ListNode(2)
let node3 = new ListNode(0)
let node4 = new ListNode(-4)
head.next = node2
node2.next = node3
node3.next = node4
node4.next = node2

console.log(detectCycle(head)?.val)